package com.koron.css2.newProjectCenter.callback;

import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageInfo;
import com.koron.css2.baseConfig.bean.PubReceiptBean;
import com.koron.css2.baseConfig.mapper.PubReceiptMapper;
import com.koron.css2.clientCenter.Enum.ProcessStateEnum;
import com.koron.css2.clientCenter.bean.AccountInfoBean;
import com.koron.css2.clientCenter.bean.CtmInfoBean;
import com.koron.css2.clientCenter.bean.UserBean;
import com.koron.css2.clientCenter.mapper.AccountInfoMapper;
import com.koron.css2.clientCenter.mapper.CtmInfoMapper;
import com.koron.css2.clientCenter.mapper.UserInfoMapper;
import com.koron.css2.clientCenter.queryBean.AccountInfoQueryBean;
import com.koron.css2.clientCenter.queryBean.CtmInfoQueryBean;
import com.koron.css2.clientCenter.queryBean.UserInfoQueryBean;
import com.koron.css2.meterService.mapper.MsInfoMapper;
import com.koron.css2.newProjectCenter.bean.PjInfoBean;
import com.koron.css2.newProjectCenter.bean.PjMeter;
import com.koron.css2.newProjectCenter.bean.PjTerminationBean;
import com.koron.css2.newProjectCenter.bean.query.PjMeterQuery;
import com.koron.css2.newProjectCenter.mapper.PjInfoMapper;
import com.koron.css2.newProjectCenter.mapper.PjMeterMapper;
import com.koron.css2.newProjectCenter.mapper.PjTerminationMapper;
import com.koron.css2.newProjectCenter.service.PjInfoService;
import com.koron.css2.newProjectCenter.vo.gcjs.GJResponseData;
import com.koron.css2.serviceManage.bean.UserInfoBean;
import com.koron.css2.systemManage.bean.OrgUserBean;
import com.koron.css2.systemManage.mapper.OrgUserMapper;
import com.koron.css2.workflow.WorkflowImpl;
import com.koron.css2.workflow.bean.ProcessCommitBean;
import com.koron.css2.workflow.bean.ProcessListBean;
import com.koron.css2.workflow.bean.ProcessListQueryBean;
import com.koron.util.Constant;
import com.koron.util.HttpUtil;
import com.koron.util.JsonUtils;
import com.koron.util.secret.StaticInfo;
import org.apache.commons.lang3.StringUtils;
import org.koron.ebs.mybatis.SessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.swan.bean.MessageBean;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import static com.koron.css2.newProjectCenter.service.gcjsData.ZjAcceptanceInfo;
import static com.koron.css2.workflow.ProcessStatusEnum.TERMINATION;

/**
 * 工程终止流程审批回调
 *
 * @author admin
 * @version 2.1
 * @since today
 */
public class PjTerminationCallback extends AbstractProcessInterface {

    private static Logger log = LoggerFactory.getLogger(PjTerminationCallback.class);

    // 每次批量修改的数量
    private static final int COUNT = 1000;

    // 注销状态值
    private static final int STOP_STATUS = 0;

    // 水表在库状态值
    private static final int MS_IN_STATUS = 1;

    // 工程报装 1 居民新装水表  5 企业新装水表
    private static final String[] PJ_TYPE = {"1", "5"};

    @Override
    public MessageBean<?> before(SessionFactory factory, UserInfoBean userInfo, String billId, String fromNodeCode, int operation) {
        try {
            if(fromNodeCode.equals(ProcessStateEnum.PROCESSING.getState()) && operation == OPERATION_SUSPEND){ // 假如是废弃
                PjInfoMapper pjInfoMapper = factory.getMapper(PjInfoMapper.class);
                PjTerminationMapper pjTerminationMapper = factory.getMapper(PjTerminationMapper.class);
                PjTerminationBean pjTermination = pjTerminationMapper.selectById(billId);
                PjInfoBean pjInfo = new PjInfoBean();
                pjInfo.setId(pjTermination.getPjId());
                pjInfo.setDelayFlag(0);
                pjInfo.setTerminationFlag(0);
                pjInfoMapper.update(pjInfo);
            }
            if (fromNodeCode.equals(ProcessStateEnum.PROCESSING.getState()) && operation == 32) {
                PjTerminationMapper pjTerminationMapper = factory.getMapper(PjTerminationMapper.class);
                PjInfoMapper pjInfoMapper = factory.getMapper(PjInfoMapper.class);
                PubReceiptMapper pubReceiptMapper = factory.getMapper(PubReceiptMapper.class);
                OrgUserMapper orgUserMapper = factory.getMapper(OrgUserMapper.class);
                String setCode = pubReceiptMapper.getWorkflowApp(userInfo.getCurWaterCode());
                // 查出当前数据
                PjTerminationBean pjTerminationBean = pjTerminationMapper.selectById(billId);
                // 查出对应的工程报装
                PjInfoBean pjInfoBean = pjInfoMapper.selectById(pjTerminationBean.getPjId());
                // 工程终止回调操作
                pjTermination(factory, pjInfoBean.getId(), pjInfoBean.getProcessState(), pjInfoBean.getPjType());
                /**
                 * 如果是需要同步报装数据到工建的水司（信宜），才会执行
                 * 报装终止程序，则传给工建不予办理办结
                 */
                if  (IPjInfoNodeCallback.GCJS_COMPANY.equals(userInfo.getCurWaterCode())) {
                    try {
                        JSONObject jsonObject = ZjAcceptanceInfo(null, "4", pjInfoBean, userInfo, factory);
                        logger.info("报装审批数据推送至工建参数：" + jsonObject.toJSONString());
                        String s = HttpUtil.sendPost(StaticInfo.interBusiApi + "/gcjs/statusUpdateReception", jsonObject.toJSONString());
                        GJResponseData responseData = JsonUtils.jsonToPojo(s, GJResponseData.class);
                        if (responseData.getErrcode() != GJResponseData.SUCCESS_CODE) {
                            logger.error("信宜报装终止办结推送至工建失败"+responseData.getMessage());
                        }
                    }catch (Exception e){
                        logger.error("信宜报装终止办结推送至工建失败",e);
                    }
                }
                String operator = "";
                if (StringUtils.isNotEmpty(pjInfoBean.getProcessHandleMan())){
                    String processHandleMan = pjInfoBean.getProcessHandleMan();
                    String[] processHandleManArray = processHandleMan.split(",");
                    OrgUserBean orgUser = orgUserMapper.selectByName(processHandleManArray[0]);
                    operator = orgUser.getCode();
                }
                if (StringUtils.isBlank(operator)){
                    String acount = userInfo.getUserInfo().getAcount();
                    OrgUserBean orgUser = orgUserMapper.selectByAccount(acount);
                    operator = orgUser.getCode();
                }
                // 4. 构造工程报装的工作流请求
                ProcessCommitBean processCommitBean = new ProcessCommitBean();
                // 4.1 billId
                processCommitBean.setBillId(pjTerminationBean.getPjId());
                // 4.2 taskId
                ProcessListQueryBean processListQueryBean = new ProcessListQueryBean();
                processListQueryBean.setOperator(operator);
                processListQueryBean.setType(2);
                processListQueryBean.setStatus(1);
                processListQueryBean.setSetCode(setCode);
                processListQueryBean.setBillId(pjTerminationBean.getPjId());
                PageInfo<ProcessListBean> page = WorkflowImpl.workflow(processListQueryBean);
                List<ProcessListBean> processListBeanList = page.getList();
                if (processListBeanList != null && processListBeanList.size() > 0) {
                    processCommitBean.setTaskId(processListBeanList.get(0).getCurTaskId());
                    // 4.3 receiptType
                    processCommitBean.setReceiptType("pj_info_new");
                    // 4.4 operation
                    processCommitBean.setOperation(16);
                    // 4.5 operator
                    processCommitBean.setOperator(operator);
                    // 4.6 setCode
                    processCommitBean.setSetCode(setCode);
                    // 4.7 单据信息是否存在
                    PubReceiptBean pubReceiptBean = pubReceiptMapper.selectPubReceipt("pj_info_new#" + pjInfoBean.getPjType());
                    Objects.requireNonNull(pubReceiptBean, "未找到单据信息");
                    // 4.8 processCode
                    processCommitBean.setProcessCode(pubReceiptBean.getProcessCode());
                    // 4.9 工作流 提交
                    WorkflowImpl.workflowsubmit(processCommitBean);
                    // 工程终止流程审批通过之后，将工程报装单据状态置为已终止
                    pjInfoBean.setProcessStateTerminated(pjInfoBean.getProcessState());
                    pjInfoBean.setProcessState(TERMINATION.getStatus());
                    pjInfoBean.setProcessName(TERMINATION.getName());
                    pjInfoBean.setProcessHandleMan(null);
                    // 流程终止后修改工程报装单的状态为已终止
                    pjInfoMapper.processTermination(pjInfoBean);
                } else {
                    return MessageBean.create(Constant.MESSAGE_INT_FAIL, "工程终止工作流回调失败：未找到工程报装的taskId", null);
                }
            }
            return MessageBean.create(Constant.MESSAGE_INT_SUCCESS, "工程终止工作流回调成功", null);
        } catch (Exception e) {
            log.error("工程终止工作流回调失败", e);
            return MessageBean.create(Constant.MESSAGE_INT_FAIL, "工程终止工作流回调失败", null);
        }
    }

    /**
     * 工程终止之后的回调操作
     * 1、将水表下面的用户信息状态置为停用
     * 2、将水表下面的客户信息状态置为停用
     * 3、将水表下面的水表信息状态置为入库
     * 4、工程类型
     * @param factory
     * @param pjId
     * @param nodeCode
     */
    public static void pjTermination(SessionFactory factory, String pjId, String nodeCode, String pjType){
        PjMeterMapper pjMeterMapper = factory.getMapper(PjMeterMapper.class);
        CtmInfoMapper ctmInfoMapper = factory.getMapper(CtmInfoMapper.class);
        AccountInfoMapper accountInfoMapper = factory.getMapper(AccountInfoMapper.class);
        UserInfoMapper userInfoMapper = factory.getMapper(UserInfoMapper.class);
        MsInfoMapper msInfoMapper = factory.getMapper(MsInfoMapper.class);

        PjMeterQuery pjMeterQuery = new PjMeterQuery();
        pjMeterQuery.setConsultId(pjId);
        List<PjMeter> pjMeterList = pjMeterMapper.getList(pjMeterQuery);

        // 将客户信息ID转换为集合
        List<String> ctmTempIdList = pjMeterList.stream().map(PjMeter::getUserCtmTempId).collect(Collectors.toList());
        // 将账户信息ID装换为集合
        List<String> accountTempIdList = pjMeterList.stream().map(PjMeter::getUserAccountTempId).collect(Collectors.toList());
        // 将用户信息ID转化为集合
        List<String> userTempIdList = pjMeterList.stream().map(PjMeter::getUserInfoTempId).collect(Collectors.toList());
        // 将水表信息ID转化为集合
        List<String> msInfoIdList = pjMeterList.stream().map(PjMeter::getMsInfoId).collect(Collectors.toList());
        // 工程单据废弃之后，需要将客户信息批量置为注销状态
        for (int i = 0; i < ctmTempIdList.size(); i = i + COUNT){
            if (ctmTempIdList.size() > i + COUNT) {
                ctmInfoMapper.batchUpdateStatus(ctmTempIdList.subList(i, i + COUNT), STOP_STATUS, CtmInfoBean.CTMTEMP);
            } else {
                ctmInfoMapper.batchUpdateStatus(ctmTempIdList.subList(i, ctmTempIdList.size()), STOP_STATUS, CtmInfoBean.CTMTEMP);
            }
        }
        // 工程单据废弃之后，需要将用户信息批量置为注销状态
        for (int i = 0; i < userTempIdList.size(); i = i + COUNT){
            if (userTempIdList.size() > i + COUNT) {
                userInfoMapper.batchUpdateStatus(userTempIdList.subList(i, i + COUNT), STOP_STATUS, UserBean.USERTEMP);
            } else {
                userInfoMapper.batchUpdateStatus(userTempIdList.subList(i, userTempIdList.size()), STOP_STATUS, UserBean.USERTEMP);
            }
        }
        // 工程单据废弃之后，需要将水表信息批量置为入库状态
        for (int i = 0; i < msInfoIdList.size(); i = i + COUNT){
            if (userTempIdList.size() > i + COUNT) {
                msInfoMapper.batchUpdateStatus(msInfoIdList.subList(i, i + COUNT), MS_IN_STATUS);
            } else {
                msInfoMapper.batchUpdateStatus(msInfoIdList.subList(i, msInfoIdList.size()), MS_IN_STATUS);
            }
        }

        // 如果是立户之后的节点，并且工程类型是：居民以及企业，需要删除所有立户产生的客户/账户/用户信息，并且将水表状态改为在库
        if (Arrays.asList(PJ_TYPE).contains(pjType) &&
                StringUtils.equalsAny(nodeCode, PjInfoService.INVITATION_CHECK, PjInfoService.INVITATION_CHECK_ACCEPT, PjInfoService.CHECK, PjInfoService.DATA_ARCHIVE)) {
            // 需要将正式表的客户信息删除
            List<CtmInfoBean> subCtmInfoTempList = null;
            for (int i = 0; i < ctmTempIdList.size(); i = i + COUNT){
                if (ctmTempIdList.size() > i + COUNT) {
                    subCtmInfoTempList = ctmInfoMapper.getListByIdList(ctmTempIdList.subList(i, i + COUNT), CtmInfoBean.CTMTEMP);
                } else {
                    subCtmInfoTempList = ctmInfoMapper.getListByIdList(ctmTempIdList.subList(i, ctmTempIdList.size()), CtmInfoBean.CTMTEMP);
                }
                List<String> ctmNoList = subCtmInfoTempList.stream().map(CtmInfoBean::getCtmNo).collect(Collectors.toList());
                CtmInfoQueryBean ctmInfoQueryBean = new CtmInfoQueryBean();
                ctmInfoQueryBean.setCtmNoList(ctmNoList);
                ctmInfoMapper.batchDelete(ctmInfoQueryBean, CtmInfoBean.CTM);
            }

            // 需要将正式表的账户信息删除
            List<AccountInfoBean> subAccountInfoTempList = null;
            for (int i = 0; i < accountTempIdList.size(); i = i + COUNT){
                if (ctmTempIdList.size() > i + COUNT) {
                    subAccountInfoTempList = accountInfoMapper.getListByIdList(accountTempIdList.subList(i, i + COUNT), AccountInfoBean.ACCOUNTTEMP);
                } else {
                    subAccountInfoTempList = accountInfoMapper.getListByIdList(accountTempIdList.subList(i, accountTempIdList.size()), AccountInfoBean.ACCOUNTTEMP);
                }
                List<String> accountNoList = subAccountInfoTempList.stream().map(AccountInfoBean::getAccountNo).collect(Collectors.toList());
                AccountInfoQueryBean accountInfoQueryBean = new AccountInfoQueryBean();
                accountInfoQueryBean.setAccountNoList(accountNoList);
                accountInfoMapper.batchDelete(accountInfoQueryBean, AccountInfoBean.ACCOUNT);
            }

            // 需要将正式表的用户信息删除
            List<UserBean> subUserInfoTempList = null;
            for (int i = 0; i < userTempIdList.size(); i = i + COUNT){
                if (userTempIdList.size() > i + COUNT) {
                    subUserInfoTempList = userInfoMapper.getListByIdList(userTempIdList.subList(i, i + COUNT), UserBean.USERTEMP);
                } else {
                    subUserInfoTempList = userInfoMapper.getListByIdList(userTempIdList.subList(i, userTempIdList.size()), UserBean.USERTEMP);
                }
                List<String> userNoList = subUserInfoTempList.stream().map(UserBean::getUserNo).collect(Collectors.toList());
                UserInfoQueryBean userInfoQueryBean = new UserInfoQueryBean();
                userInfoQueryBean.setUserNoList(userNoList);
                userInfoMapper.batchDelete(userInfoQueryBean, UserBean.USER);
            }
        }
    }
}
